<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Document</title>
    <style type="text/css">
        .container {
        }

        .container .cart {
            width: 300px;
            margin: auto;
        }

        .container .title {
            background-color: lightblue;
            height: 40px;
            line-height: 40px;
            text-align: center;
            /*color: #fff;*/
        }

        .container .total {
            background-color: #FFCE46;
            height: 50px;
            line-height: 50px;
            text-align: right;
        }

        .container .total button {
            margin: 0 10px;
            background-color: #DC4C40;
            height: 35px;
            width: 80px;
            border: 0;
        }

        .container .total span {
            color: red;
            font-weight: bold;
        }

        .container .item {
            height: 55px;
            line-height: 55px;
            position: relative;
            border-top: 1px solid #ADD8E6;
        }

        .container .item img {
            width: 45px;
            height: 45px;
            margin: 5px;
        }

        .container .item .name {
            position: absolute;
            width: 90px;
            top: 0;
            left: 55px;
            font-size: 16px;
        }

        .container .item .change {
            width: 100px;
            position: absolute;
            top: 0;
            right: 50px;
        }

        .container .item .change a {
            font-size: 20px;
            width: 30px;
            text-decoration: none;
            background-color: lightgray;
            vertical-align: middle;
        }

        .container .item .change .num {
            width: 40px;
            height: 25px;
        }

        .container .item .del {
            position: absolute;
            top: 0;
            right: 0px;
            width: 40px;
            text-align: center;
            font-size: 40px;
            cursor: pointer;
            color: red;
        }

        .container .item .del:hover {
            background-color: orange;
        }
    </style>
</head>
<body>
<div id="app">
    <div class="container">

        <!-- 2.把组件渲染到页面上 -->
        <my-cart></my-cart>

    </div>
</div>
<script src="../lib/vue_2.5.22.js" type="text/javascript"></script>
<script type="text/javascript">


    // 1.把静态页面转换成组件化模式
    // 1.1.标题组件
    var cartTitle = {
        // 2.2. 子组件通过props形式接收父组件传递过来的name数据
        props: ['uname'],
        template: `
        <div class="title">{{uname}} 的商品</div>`,
    };

    // 1.2.商品列表组件
    var cartList = {
        // 3.2.把列表数据动态渲染到页面上
        props: ['list'],

        // 3.3.给按钮添加点击事件把需要删除的id传递过来
        // @click='del(item.id)'
        // #
        // @blur='changeNum(item.id, $event)'
        // 输入框失去焦点的时候, 更改商品的数量, 需要将当前商品的id传递过来
        template: `
        <div>
            <div class="item" v-for="(item, index) in list" :key="item.id">
                <img  v-bind:src="item.img"/>
                <div class="name">{{item.name}}</div>
                <div class="change">
                    <a href="" @click.prevent="sub(item.id)">－</a>
                    <input class="num" type="text" v-bind:value="item.num" @blur="changeNum(item.id, $event)"/>
                    <a href="javascript:;" @click.prevent="add(item.id)">＋</a>
                </div>
                <div class="del" @click="del(item.id)">×</div>
            </div>
        </div>`,
        methods: {
            changeNum: function (id, event) {
                console.log(id, event.target.value);
                this.$emit('change-num', {
                    id: id,
                    num: event.target.value
                });
            },
            del: function (id) {
                // console.log(id)
                // 3.4.子组件中不推荐操作父组件的数据, 有可能多个子组件使用父组件的数据
                // 所有我们需要把id数据传递给父组件, 让父组件操作数据
                this.$emit('cart-del', id);
            },
            add: function (id) {
                this.$emit('cart-add', id);
            },
            sub: function (id) {
                this.$emit('cart-sub', id);
            }
        }
    };

    // 1.3.商品结算组件
    var cartTotal = {
        // 2.3. 子组件通过props形式接收父组件传递过来的list数据
        props: ['list'],
        template: `
        <div class="total">
            <span>总结: {{total}}</span>
            <button>结算</button>
        </div>`,
        computed: {
            // 2.4.计算商品的总价, 并渲染到页面上
            total: function () {
                // 计算当前的总价
                var t = 0;
                this.list.forEach(item => {
                    t += (item.price * item.num)
                });
                return t;
            }
        }

    }


    // 1.4.定义一个全局组件 my-cart
    Vue.component('my-cart', {
        data: function () {
            // 2.1.父组件向子组件以属性传递的形式, 传递数据
            // 向标题组件传递name属性, 向商品结算组件传递list属性
            return {
                name: 'hliushi',
                list: [{
                    id: 1,
                    name: 'TCL彩电',
                    price: 1000,
                    num: 1,
                    img: '../img/a.jpg'
                }, {
                    id: 2,
                    name: '机顶盒',
                    price: 1000,
                    num: 1,
                    img: '../img/b.jpg'
                }, {
                    id: 3,
                    name: '海尔冰箱',
                    price: 1000,
                    num: 1,
                    img: '../img/c.jpg'
                }, {
                    id: 4,
                    name: '小米手机',
                    price: 1000,
                    num: 1,
                    img: '../img/d.jpg'
                }, {
                    id: 5,
                    name: 'PPTV电视',
                    price: 1000,
                    num: 2,
                    img: '../img/e.jpg'
                }]
            }
        },

        // 1.6.引入子组件
        // @cart-del="delCart($event)" @cart-add="cartAdd($event)"
        // 父组件通过事件监听, 接收子组件的数据
        template: `
          <div class="cart">
              <cart-title :uname="name"></cart-title>
              <cart-list :list="list" @cart-del="delCart($event)" @cart-add="cartAdd($event)" @cart-sub="cartSub($event)" @change-num="changeNum($event)"></cart-list>
              <cart-total :list="list"></cart-total>
         </div>`,

        // 1.5.注册子组件
        components: {
            'cart-title': cartTitle,
            'cart-list': cartList,
            'cart-total': cartTotal,
        },
        methods: {
            // 3.6.根据id删除list中对应的数据
            delCart: function (id) {
                // 1.找到id所对应数据的索引
                var index = this.list.findIndex(item => {
                    return item.id === id;
                });

                // 2.根据所您删除对应数据
                this.list.splice(index, 1);
            },
            cartAdd: function (id) {
                // 1.找到id所对应数据的索引
                var index = this.list.findIndex(item => {
                    return item.id === id;
                });

                this.list[index].num++;
            },
            cartSub: function (id) {
                // 1.找到id所对应数据的索引
                var index = this.list.findIndex(item => {
                    return item.id === id;
                });

                if (this.list[index].num === 0) {
                    alert("不能再减少商品数量了, 亲");
                    return;
                }
                this.list[index].num--;
            },

            changeNum: function (food) {
                console.log(food);
                // todo 使用一种方法,  分为三种情况: 输入与变更, 加号变更, 减号变更

                // 根据子组件传递过来的数据, 更新list中对应的数据
                // some()方法测试数组中是否至少有一个元素通过了由提供的函数实现的测试。 它返回一个布尔值
                this.list.some(item => {
                    if (item.id === food.id) {
                        item.num = food.num;
                        // 终止遍历
                        return true;
                    }
                })

            }
        }
    })


    let vm = new Vue({
        el: "#app",
        data: {}
    });
</script>
</body>
</html>